﻿using LightOMator.Model;
using Microsoft.Xna.Framework.Media;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight.Command;
using LightOMator.Helper;
using Windows.Networking.Proximity;
using Windows.Networking.Sockets;
using LightOMator.Bluetooth;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using Coding4Fun.Toolkit.Controls;
using System.IO.IsolatedStorage;
using Cimbalino.Phone.Toolkit.Services;

namespace LightOMator.ViewModel
{
    public class MainViewModel : BusyViewModel
    {

        private BluetoothConnection _connection;
        public BluetoothConnection Connection
        {
            get { return _connection; }
            set
            {
                _connection = value;
                RaisePropertyChanged();
            }
        }

        private Color _singleColor = Colors.Red;
        public Color SingleColor
        {
            get { return _singleColor; }
            set
            {
                if (value != _singleColor)
                {
                    _singleColor = value;
                    RaisePropertyChanged();
                    onSingleColorChanged(value);
                }
            }
        }

        private Color _multipleColor = Colors.Green;
        public Color MultipleColor
        {
            get { return _multipleColor; }
            set
            {
                if (value != _multipleColor)
                {
                    _multipleColor = value;
                    RaisePropertyChanged();
                }
            }
        }

        private Color _selectedMultipleColor;
        public Color SelectedMultipleColor
        {
            get { return _selectedMultipleColor; }
            set
            {
                if (value != _selectedMultipleColor)
                {
                    _selectedMultipleColor = value;
                    RaisePropertyChanged();
                }
            }
        }

        private ObservableCollection<Color> _multipleColors = new ObservableCollection<Color>();
        public ObservableCollection<Color> MultipleColors
        {
            get { return _multipleColors; }
            set
            {
                _multipleColors = value;
            }
        }

        private int _multipleKeepOnTimePromille = 300;
        public int MultipleKeepOnTimePromille
        {
            get { return _multipleKeepOnTimePromille; }
            set
            {
                if (value != _multipleKeepOnTimePromille)
                {
                    _multipleKeepOnTimePromille = value;
                    RaisePropertyChanged();
                    onMultipleKeepOnTimeChanged(getKeepOnTime(value));
                }
            }
        }

        private int _multipleFadeInTimePromille = 300;
        public int MultipleFadeInTimePromille
        {
            get { return _multipleFadeInTimePromille; }
            set
            {
                if (value != _multipleFadeInTimePromille)
                {
                    _multipleFadeInTimePromille = value;
                    RaisePropertyChanged();
                    onMultipleFadeInTimeChanged(getFadeInTime(value));
                }
            }
        }

        private int _pivotIndex;
        public int PivotIndex
        {
            get { return _pivotIndex; }
            set
            {
                if (value != _pivotIndex)
                {
                    _pivotIndex = value;
                    IsMultipleMode = (value == 1);
                    IsSavedMode = (value == 2);
                    RaisePropertyChanged();
                }
            }
        }

        private bool _isMultipleMode;
        public bool IsMultipleMode
        {
            get { return _isMultipleMode; }
            set
            {
                if (value != _isMultipleMode)
                {
                    _isMultipleMode = value;
                    RaisePropertyChanged();
                }
            }
        }

        private bool _isSavedMode;
        public bool IsSavedMode
        {
            get { return _isSavedMode; }
            set
            {
                if (value != _isSavedMode)
                {
                    _isSavedMode = value;
                    RaisePropertyChanged();
                }
            }
        }
        
        private ObservableCollection<FadeCollection> _savedCollections;
        public ObservableCollection<FadeCollection> SavedCollections
        {
            get { return _savedCollections; }
            set
            {
                _savedCollections = value;
            }
        }

        private FadeCollection _selectedSavedCollection;
        public FadeCollection SelectedSavedCollection
        {
            get { return _selectedSavedCollection; }
            set 
            {
                if (value != _selectedSavedCollection)
                {
                    _selectedSavedCollection = value;
                    RaisePropertyChanged();
                    onSavedCollectonChanged(value);
                }
            }
        }



        public RelayCommand AddMultipleColorCommand { get; private set; }
        public RelayCommand RemoveMultipleColorCommand { get; private set; }
        public RelayCommand MultipleSaveFadesCommand { get; private set; }
        public RelayCommand EditFadesCommand { get; private set; }
        public RelayCommand SettingsCommand { get; private set; }

        public MainViewModel()
        {
            AddMultipleColorCommand = new RelayCommand(addMultipleColor);
            RemoveMultipleColorCommand = new RelayCommand(removeMultipleColor);
            MultipleSaveFadesCommand = new RelayCommand(saveMultipleFades);
            EditFadesCommand = new RelayCommand(editMultipleFades);
            SettingsCommand = new RelayCommand(navigateToSettingsPage);
            if (IsInDesignMode)
            {
                MultipleColors.Add(Colors.Red);
                MultipleColors.Add(Colors.Green);
                MultipleColors.Add(Colors.Blue);
            }
        }

        private void editMultipleFades()
        {
            NavigationService service = new NavigationService();
            service.NavigateTo("/View/EditPage.xaml");
        }

        private void navigateToSettingsPage()
        {
            NavigationService service = new NavigationService();
            service.NavigateTo("/View/SettingsPage.xaml");
        }


        public async override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
        {
            if (_connection == null)
            {
                if (!IsolatedStorageSettings.ApplicationSettings.TryGetValue<ObservableCollection<FadeCollection>>("_collections", out _savedCollections))
                {
                    _savedCollections = new ObservableCollection<FadeCollection>();
                }
                Connection = new BluetoothConnection();
                Connection.ConnectionStateChanged += onConnectionStateChanged;
                await _connection.Connect();
                Settings settings = Settings.Instance;
                PivotIndex = (int)settings.StartPage;
            }
        }

        private void onConnectionStateChanged(object sender, BluetoothConnection.ConnectionState e)
        {
            string title = null;
            string message = null;
            if (e == BluetoothConnection.ConnectionState.Connected)
            {
                title = "Connected";
                message = "You are now connected to the light source";
            }
            else if (e == BluetoothConnection.ConnectionState.NotConnected)
            {
                title = "Connection Lost";
                message = "You are now disconnected from the light source";
            }
            if (title != null || message != null)
            {
                var toast = new ToastPrompt
                {
                    Title = title,
                    Message = message,
                    ImageSource = new BitmapImage(new Uri("\\Assets\\ApplicationIcon.png", UriKind.RelativeOrAbsolute)),
                    TextOrientation = System.Windows.Controls.Orientation.Vertical,
                    MillisecondsUntilHidden = 5 * 1000
                };
                toast.Show();
            }
        }

        private void addMultipleColor()
        {
            MultipleColors.Add(MultipleColor);
            onMultipleColorsChanged();
            RaisePropertyChanged("MultipleColors");
        }

        private void removeMultipleColor()
        {
            lock (MultipleColors)
            {
                if (MultipleColors.Count > 0)
                {
                    MultipleColors.RemoveAt(MultipleColors.Count - 1);
                    onMultipleColorsChanged();
                    RaisePropertyChanged("MultipleColors");
                }
            }
        }

        private async void onSingleColorChanged(Color color)
        {
            await Connection.WriteColor(color);
        }

        private FadeCollection getCurrentFadeCollection()
        {
            FadeCollection collection = new FadeCollection
            { 
                FadeMode = Model.FadeMode.DirectFade
            };
            int fadeInTimeMs = getFadeInTime(MultipleFadeInTimePromille);
            int keepOnTimeMs = getKeepOnTime(MultipleKeepOnTimePromille);
            List<Fade> fades = new List<Fade>(MultipleColors.Count());
            foreach (Color color in MultipleColors)
            {
                Fade fade = new Fade { Color = color, FadeInTimeMs = fadeInTimeMs, KeepOnTimeMs = keepOnTimeMs };
                fades.Add(fade);
            }
            collection.Fades = fades;

            return collection;
        }

        private int getKeepOnTime(int keepOnTimeMs)
        {
            Settings settings = Settings.Instance;
            return settings.KeepOnStartRangeMs + ((settings.KeepOnEndRangeMs - settings.KeepOnStartRangeMs) * keepOnTimeMs) / 1000;
        }

        private int getFadeInTime(int fadeInTimeMs)
        {
            Settings settings = Settings.Instance;
            return settings.FadeInStartRangeMs + ((settings.FadeInEndRangeMs - settings.FadeInStartRangeMs) * fadeInTimeMs) / 1000;
        }

        private async void onMultipleColorsChanged()
        {
            if (MultipleColors.Count > 1)
            {
                FadeCollection collection = getCurrentFadeCollection();
                await Connection.WriteFades(collection);
            }
        }

        private async void onMultipleKeepOnTimeChanged(int keepOnTimeMs)
        {
            if (MultipleColors.Count > 1)
            {
                await Connection.WriteFadesKeepOnTimeMs(keepOnTimeMs);
            }
        }

        private async void onMultipleFadeInTimeChanged(int fadeInTimeMs)
        {
            if (MultipleColors.Count > 1)
            {
                await Connection.WriteFadesFadeInTimeMs(fadeInTimeMs);
            }
        }

        private void saveMultipleFades()
        {

            InputPrompt prompt = new InputPrompt
            {
                Message = "Name of your fade collection:",
                MessageTextWrapping = System.Windows.TextWrapping.Wrap,
                IsSubmitOnEnterKey = true,
                IsCancelVisible = true

            };
            prompt.Completed += onMultpleSaveNameCompleted;
            prompt.Show();
        }

        private void onMultpleSaveNameCompleted(object sender, PopUpEventArgs<string, PopUpResult> e)
        {
            if (e.PopUpResult == PopUpResult.Ok)
            {
                string name = e.Result;
                FadeCollection collection = getCurrentFadeCollection();
                collection.Name = name;
                collection.CreationTime = DateTime.Now;

                FadeCollection.CurrentFadeCollection = collection;
                SavedCollections.Add(collection);
                //Windows.Storage.ApplicationData.Current.LocalSettings.Values["_collections"] = SavedCollections;
                IsolatedStorageSettings.ApplicationSettings["_collections"] = SavedCollections;
                IsolatedStorageSettings.ApplicationSettings.Save();
                RaisePropertyChanged("SavedCollections");
            }
        }

        private async void onSavedCollectonChanged(FadeCollection collection)
        {
            FadeCollection.CurrentFadeCollection = collection;
            await Connection.WriteFades(collection);
        }


    }
}
